import {_decorator, Component, Node, Prefab, instantiate, Vec3, EventTouch, UITransform, tween, v3, CCInteger} from "cc"
import {AvatarView} from "db://assets/script/game/desk/view/avatarView";
import {pb} from "db://assets/script/network/ws/proto";
import {CardView} from "db://assets/script/game/majiang/view/cardView";
import {pt} from "db://assets/script/game/player/api";
import {Horizontal} from "db://assets/script/common/horizontal";
import {ViewUtil} from "db://oops-framework/core/utils/ViewUtil";
import {calculateScreenPosToSpacePosByPos} from "db://assets/script/utils/nodeUtils";
import {smc} from "db://assets/script/game/common/singletonModuleComp";

const {ccclass, property} = _decorator

@ccclass("PlayerSideView")
export class PlayerSideView extends Component {

    @property({
        type: Node,
        tooltip: "头像"
    })
    avatar: Node

    @property({
        type: Node,
        tooltip: "准备手势"
    })
    readyHand: Node

    @property({
        type: Node,
        tooltip: "麻将牌显示位置"
    })
    cards: Node

    @property({
        type: Prefab,
        tooltip: "麻将牌显示"
    })
    cardPrefab: Prefab

    @property({
        type: Node,
        tooltip: "麻将牌出牌位置"
    })
    cardDropped: Node

    @property({
        type: Prefab,
        tooltip: "麻将牌出牌prefab"
    })
    cardDroppedPrefab: Prefab

    @property({
        type: Prefab,
        tooltip: "麻将牌光效"
    })
    cardEffectPrefab: Prefab

    @property({
        type: CCInteger,
        tooltip: "出牌x位置"
    })
    chuPaiX: number

    @property({
        type: CCInteger,
        tooltip: "出牌y位置"
    })
    chuPaiY: number



    allCardNode: {}
    myCardController: Horizontal
    // 选中的牌
    selectedIndex: number

    onLoad() {
        this.allCardNode = {}
        this.myCardController = new Horizontal(0, 60)
        this.cards.removeAllChildren()
        this.cardDropped.removeAllChildren()
    }

    // 是否显示玩家
    togglePlayer(isShow: boolean) {
        this.node.active = isShow
    }

    // 切换准备手势
    toggleReadyHand(isReady: boolean) {
        this.readyHand.active = isReady
    }

    // 更新头像
    updateAvatar(avatar: string, nickname: string, score: number) {
        const avatarView = this.avatar.getComponent(AvatarView)
        avatarView.updateAvatar(avatar)
        avatarView.updateNickname(nickname)
        avatarView.updateScore(score.toString())
    }

    // 重置 cards
    resetCards() {
        this.cards.removeAllChildren()
        this.cardDropped.removeAllChildren()
        this.myCardController.reset()
    }

    // 添加牌
    addCard(tile: pb.ITileInfo, active: boolean) {
        const cardNode = instantiate(this.cardPrefab)
        const cardView = cardNode.getComponent(CardView)
        if (tile.tid != pt.TileId.noCard) {
            const isOk = cardView.updateCardIconByTid(tile.tid, tile.index)
            if (!isOk) {
                cardNode.destroy()
                console.error("no such card", tile.tid)
                return
            }
        } else {
            // 只设置属性，不更新牌面
            cardView.tid = tile.tid
            cardView.tileIndex = tile.index
        }
        cardNode.parent = this.cards
        cardNode.active = active
        this.allCardNode[tile.index] = cardNode
        this.myCardController.addCell()
        this.cards.getComponent(UITransform).width = this.myCardController.gridWidth
    }

    updateCardPosition() {
        const cardsPos = this.cards.getPosition()
        let posX: number
        for (let i = 0; i < this.cards.children.length; i++) {
            posX = this.myCardController.getPositionByIndex(i)
            this.cards.children[i].setPosition(new Vec3(posX, cardsPos.y, cardsPos.z))
        }
    }

    // 监听牌移动
    listenPlayerCard() {
        this.cards.on(Node.EventType.TOUCH_START, (event: EventTouch) => {
            const pos = ViewUtil.calculateScreenPosToSpacePos(event, this.cards)
            const touchIndex = this.myCardController.getIndexByPosition(pos.x)
            if (touchIndex !== this.selectedIndex && this.selectedIndex > -1) {
                // 将之前选中的归位
                const posX = this.myCardController.getPositionByIndex(this.selectedIndex)
                this.moveBack(this.cards.children[this.selectedIndex], new Vec3(posX, this.cards.getPosition().y, 0))
            }
            this.selectedIndex = touchIndex
        })

        this.cards.on(Node.EventType.TOUCH_MOVE, (event: EventTouch) => {
            const startPos = event.getUIStartLocation()
            let pos = calculateScreenPosToSpacePosByPos(startPos, this.cards)
            // 计算选中的牌
            const nodeIndex = this.myCardController.getIndexByPosition(pos.x)
            const targetNode = this.cards.children[nodeIndex]
            pos = ViewUtil.calculateScreenPosToSpacePos(event, this.cards)
            targetNode.setPosition(pos)
            // console.log("moving", targetNode, nodeIndex)
        })

        this.cards.on(Node.EventType.TOUCH_END, (event: EventTouch) => {
            console.log("move end")
            // 未离开点击区域, 不出牌
            // 返回选中状态
            const startPos = event.getUIStartLocation()
            const pos = calculateScreenPosToSpacePosByPos(startPos, this.cards)
            const nodeIndex = this.myCardController.getIndexByPosition(pos.x)
            const posX = this.myCardController.getPositionByIndex(nodeIndex)
            // this.moveBack(this.cards.children[nodeIndex], new Vec3(posX, this.cards.getPosition().y, 0))
            this.selected(this.cards.children[nodeIndex], new Vec3(posX, this.cards.getPosition().y, 0))
        })

        this.cards.on(Node.EventType.TOUCH_CANCEL, (event: EventTouch) => {
            // 离开点击区域, 可以出牌
            const cardView = this.cards.children[this.selectedIndex].getComponent(CardView)
            if (cardView.tid !== pt.TileId.noCard) {
                // 是真的牌，可以出
                // console.log("player card", cardView.tileIndex, cardView.tid)
                smc.gameMj.addChuPaiComp(cardView.tid, cardView.tileIndex)
                // 扔牌
                // this.dropCard(this.cards.children[this.selectedIndex], cardView.tid, cardView.tileIndex)
            }
        })
    }

    moveBack(node: Node, pos: Vec3) {
        tween(node).stop()
        const time = this.node.getPosition().length() / 1000
        tween(node).to(time, {
            position: pos,
        }, {
            easing: "fade"
        }).start()
    }

    selected(node: Node, pos: Vec3) {
        tween(node).stop()
        tween(node).to(0.1, {
            position: new Vec3(pos.x, pos.y + 20, pos.z)
        }, {
            easing: "fade"
        }).start()
    }

    dropCard(tid: pb.TileId, tileIndex: number) {
        const selected = this.cards.children[this.selectedIndex]
        if (!selected || tid === pt.TileId.noCard) {
            console.error('no selected node', selected, tid)
            return
        }
        // 选中的牌移到中间
        tween(selected).to(1, {
            // 移动位置
            position: v3(this.chuPaiX, this.chuPaiY, 0),
            scale: v3(0.8, 0.8, 1), // 缩放
        }, {
            easing: "sineOut"
        }).call(() => {
            // 显示光圈
            const node = instantiate(this.cardEffectPrefab)
            node.parent = this.cards
            node.active = true
            node.setPosition(0, 0, 0)
            selected.addChild(node)
        }).delay(0.8).call(() => {
            this.addDropCard(tid, tileIndex)
            // TODO 删除牌，更新牌的位置
            selected.destroy()
        }).start()
    }

    addDropCard(tid, tileIndex) {
        const dropNode = instantiate(this.cardDroppedPrefab)
        const cardView = dropNode.getComponent(CardView)
        const isOk = cardView.updateCardIconByTid(tid, tileIndex)
        if (!isOk) {
            dropNode.destroy()
            console.error("no such card", tid)
            return
        }
        dropNode.parent = this.cardDropped
    }
    // // 删除一张
    // dropCard(tileIndex: number) {
    //     const cardNode = this.allCardNode[tileIndex]
    //     if (cardNode) {
    //         cardNode.parent = null
    //     }
    // }
}